package pcmd_tab;

use strict;
use warnings;

use Tk;
use Tk::HList;
use Tk::BrowseEntry;


#---------------------------------
# New: constructor of the class --
#---------------------------------
sub new {
    my $arg0 = shift;
    my $cls = ref($arg0) || $arg0;
    
    my $self = {};
    bless $self, $cls;

    $self->init(@_);
    
    return $self;
}


#--------------------------
# Init: Initialize class --
#--------------------------
sub init {
    my $self = shift;
    my $gui = shift;
    my $config = shift;
    my $frame = shift;
    my $name = shift;
    my $callbacks = shift;
    
        
    # Store parameters as class variables
    $self->{gui} = $gui;
    $self->{config} = $config;
    $self->{frame} = $frame;
    $self->{name} = $name;
    $self->{callbacks} = $callbacks;
    
    # Init other class variables
    $self->{anchor_store} = '0';
    $self->{selection} = {};
    $self->{history} = [];
    
    # Create HList
    $self->{hlist} = $frame->Scrolled(
        'HList',
        -scrollbars => 'osoe',
        -columns => scalar(@{$self->{config}{headers}}), 
        -header => 1,
        -background => $config->{colors}{background},
        -command => $self->{callbacks}{command},
    )->pack(-side => 'bottom', -expand => 1, -fill => 'both'); 
    $self->{hlist}->columnWidth(0, -char => 40);
    
    # Create label
    $self->{title} = '';
    $self->{bentry} = $frame->BrowseEntry( 
        -variable => \$self->{title},
        -label => $self->{gui}{texts}{'curr_dir'}, 
        #-choices => \@header_nums ,
        -browsecmd => sub { &{$self->{callbacks}{title_mod}}($self->{title}) },
    )->pack(-side => 'top', -fill => 'y', -anchor => 'nw');
    $self->{bentry}->Subwidget('entry')->Subwidget('entry')->configure(-background => $config->{colors}{background},);
    $self->{bentry}->bind('<Return>', sub { &{$self->{callbacks}{title_mod}}($self->{title}) });

    # Bindings
    $self->set_bindings();
    
    # Update headers
    $self->update_headers();
    
};


#------------------
# Update headers --
#------------------
sub update_headers {
    my $self = shift;

    foreach my $idx (0..$#{$self->{'config'}->{'headers'}}) {
        if ($self->{hlist}->headerExists($idx)) {
            $self->{hlist}->headerConfigure($idx, -text => $self->{gui}{'texts'}->{$self->{'config'}->{'headers'}->[$idx]});
        } else {
            $self->{hlist}->headerCreate($idx, -text => $self->{gui}{'texts'}->{$self->{'config'}->{'headers'}->[$idx]});
        };
    };    

};


#---------------
# Update tree --
#---------------
sub update_tree {
    my $self = shift;
    my $list = shift;
    
    my @orig_children = $self->{'hlist'}->infoChildren(''); 

    foreach my $idx (0..$#{$list}) {
        unless ($self->{hlist}->infoExists($idx)) { $self->{hlist}->add($idx, -itemtype => 'imagetext',) };
        
        my $style = ($self->is_selected($idx)) ? $self->{gui}{styles}{selected} : $self->{gui}{styles}{normal};
        
        # Update 0. item
        if ($self->{hlist}->itemExists($idx, 0)) {
            $self->{hlist}->itemConfigure( $idx, 0,
                -itemtype => 'imagetext',
                -text => $list->[$idx]->get_field($self->{'config'}->{'headers'}->[0]),
                -image => $self->{gui}{'images'}->{$list->[$idx]->get_type()},
                -style => $style,
            );
        } else {
            $self->{hlist}->itemCreate( $idx, 0,
                -itemtype => 'imagetext',
                -text => $list->[$idx]->get_field($self->{'config'}->{'headers'}->[0]),
                -image => $self->{gui}{'images'}->{$list->[$idx]->get_type()},
                -style => $style,
            );
        };

        # Update rest items
        foreach my $col (1..$#{$self->{'config'}->{'headers'}}) {

            if ($self->{hlist}->itemExists($idx, $col)) {
                $self->{hlist}->itemConfigure( $idx, $col,
                    -itemtype => 'imagetext',
                    -text => $list->[$idx]->get_field($self->{'config'}->{'headers'}->[$col]),
                    -style => $style,
                );
            } else {
                $self->{hlist}->itemCreate( $idx, $col,
                    -itemtype => 'imagetext',
                    -text => $list->[$idx]->get_field($self->{'config'}->{'headers'}->[$col]),
                    -style => $style,
                );
            };
        };
    };
    
    # Remove old item which are not necessary
    if (scalar(@orig_children) > scalar(@{$list})) {
        foreach my $path (scalar(@{$list})..$#orig_children) {
            $self->{hlist}->delete('entry', $path);
        };        
    };
    
};


#----------------
# Update style --
#----------------
sub update_style {
    my $self = shift;
    my $paths = shift;
    
    foreach my $path (@{$paths}) {
        my $style = ($self->is_selected($path)) ? $self->{gui}{styles}{selected} : $self->{gui}{styles}{normal};
                
        foreach my $col (0..$#{$self->{config}{headers}}) {
            $self->{hlist}->itemConfigure( $path, $col, -style => $style,);
        }
    };    
};


#----------------
# Set bindings --
#----------------
sub set_bindings {
    my $self = shift;
        
    # FocusIn
    $self->{hlist}->bind('<FocusIn>' => sub {
        # Call callback function
        &{$self->{callbacks}{focus_in}}();
    });
    
    # Tab
    $self->{hlist}->bind('<Tab>' => sub {
        &{$self->{callbacks}{tab}}();
    });
    
    # Insert
    $self->{hlist}->bind('<Insert>' => sub {
        $self->update_selection($self->{hlist}->infoAnchor());
        $self->update_style([$self->{hlist}->infoAnchor()]);
        $self->{hlist}->UpDown('next');
    });
};


#----------------
# Get selected --
#----------------
sub get_selected {
    my $self = shift;
    
    return $self->{hlist}->infoAnchor();
};


#-----------------
# Get selection --
#-----------------
sub get_selection {
    my $self = shift;
    
    if (keys %{$self->{selection}}) {    
        return (keys %{$self->{selection}});
    } else {
        if ( $self->{hlist}->infoAnchor()) {
            return  $self->{hlist}->infoAnchor();
        } else {
            return ();
        };
    };
};


#-------------------
# Clear selection --
#-------------------
sub clear_selection {
    my $self = shift;
    
    %{$self->{selection}} = ();
};


#--------------------
# Update selection --
#--------------------
sub update_selection {
    my $self = shift;
    my $path = shift;
        
    if (defined $self->{selection}{$path}) {
        delete $self->{selection}{$path};
    } else {
        $self->{selection}{$path} = '';
    };
};


#---------------
# is selected --
#---------------
sub is_selected {
    my $self = shift;
    my $path = shift;
    
    return (defined $self->{selection}{$path});
};


#--------------
# Set anchor --
#--------------
sub set_anchor {
    my $self = shift;
    my $restore = shift;   
    
    my $path = (defined $restore) ? $self->{anchor_store} : '0';
    
    $self->{hlist}->selectionClear();
    $self->{hlist}->selectionSet($path);
    $self->{hlist}->anchorSet($path);
};


#----------------
# Clear anchor --
#----------------
sub clear_anchor {
    my $self = shift;
    
    # Store anchor path
    $self->{anchor_store} = $self->{hlist}->infoAnchor();
    unless ($self->{anchor_store}) { $self->{anchor_store} = '0'; };
    
    $self->{hlist}->selectionClear();
    $self->{hlist}->anchorClear();
};


#---------
# Focus --
#---------
sub focus {
    my $self = shift;
    
    $self->{hlist}->focus();
};


#-------------
# Set title --
#-------------
sub set_title {
    my $self = shift;
    my $title = shift;
    
    $self->{title} = $title;
    
    $self->add_to_history($title);
};


#------------------
# Add to history --
#------------------
sub add_to_history {
    my $self = shift;
    my $dir = shift;    

    foreach my $idx (reverse (0..$#{$self->{history}})) {
        if ($self->{history}[$idx] eq $dir) {
             splice(@{$self->{history}}, $idx, 1);
        };
    };

    unshift(@{$self->{history}}, $dir);
    
    if (scalar(@{$self->{history}}) > 5) {
        pop(@{$self->{history}});
    };
    
    $self->{bentry}->configure(-choices => $self->{history} );
};



1;
